import sys
import time

import win32api
import win32event
import win32service
import win32serviceutil
import servicemanager
import win32serviceutil
import win32security
import win32con
import win32evtlog
import win32security
import win32evtlogutil


import win32service 

import win32event 

import os

import socket

def signal_child(service, command):
    if command == 'stop':
        return win32serviceutil.StopService(service)
    elif command == 'restart':
        return win32serviceutil.RestartService(service)
    elif command == 'query':
#        print('hello')
        x=win32serviceutil.QueryServiceStatus(service)
#        print(x)
        return x[1]
    elif command == 'start':
        return win32serviceutil.StartService(service)

def watch(service_name):
    while 1:
        result=signal_child(service_name,'query')
        if result==4:
            pass
            #print('yes')
        else:
            log_to_windows(service_name+' is stopped, restartting... ')
            signal_child(service_name,'start')
        time.sleep(10)
def log_to_windows(log):
    ph = win32api.GetCurrentProcess()
    th = win32security.OpenProcessToken(ph, win32con.TOKEN_READ)
    my_sid = win32security.GetTokenInformation(th, win32security.TokenUser)[0]
     
    applicationName = "python-watchdog"
    eventID = 1001
    category = 5	# Shell
    myType = win32evtlog.EVENTLOG_WARNING_TYPE
    #descr = ["A warning", "An even more dire warning"]
    descr=[log]
    data = "Application\0Data".encode("ascii")
     
    win32evtlogutil.ReportEvent(applicationName, eventID, eventCategory=category, 
            eventType=myType, strings=descr, data=data, sid=my_sid)


class MyService(win32serviceutil.ServiceFramework):

    _svc_name_ = "python-watchdog"
    _svc_display_name_ = "python-watchdog"
    _svc_description_ = "python-watchdog"
    

    def __init__(self, args):
        self.log('init')
        win32serviceutil.ServiceFramework.__init__(self, args)
        self.stop_event = win32event.CreateEvent(None, 0, 0, None)

    def SvcDoRun(self):
        self.ReportServiceStatus(win32service.SERVICE_START_PENDING)
        try:
            self.ReportServiceStatus(win32service.SERVICE_RUNNING)
            self.log('start')
            #log_to_windows('hello,world')
            self.start()

            self.log('wait')
            win32event.WaitForSingleObject(self.stop_event, win32event.INFINITE)
            self.log('done')
        except BaseException as e:
            self.log('Exception : %s' % e)
            self.SvcStop()

    def SvcStop(self):
        self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
        self.log('stopping')
        self.stop()
        self.log('stopped')
        win32event.SetEvent(self.stop_event)
        self.ReportServiceStatus(win32service.SERVICE_STOPPED)

    def start(self):
        service='TxQBService'
        watch(service)
        #time.sleep(10000)

    def stop(self):
        pass

    def log(self, msg):
        servicemanager.LogInfoMsg(str(msg))

    def sleep(self, minute):
        win32api.Sleep((minute*1000), True)

if __name__ == "__main__":
    
    
    if len(sys.argv) == 1:
        servicemanager.Initialize()
        servicemanager.PrepareToHostSingle(MyService)
        servicemanager.StartServiceCtrlDispatcher()
    else:
        win32serviceutil.HandleCommandLine(MyService)
